﻿#region zh-CHS 2006 - 2008 DemoSoft 团队 | en 2006 - 2008 DemoSoft Team

//     NOTES
// ---------------
//
// This file is a part of the MMOSE(Massively Multiplayer Online Server Engine) for .NET.
//
//                              2006-2008 DemoSoft Team
//
//
// First Version : by H.Q.Cai - mailto:caihuanqing@hotmail.com

/***************************************************************************
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published
 *   by the Free Software Foundation; either version 2.1 of the License, or
 *   (at your option) any later version.
 *
 ***************************************************************************/

#region zh-CHS 包含名字空间 | en Include namespace
using System;
using System.Diagnostics;
using System.Threading;
using Demo.Mmose.Core.Common;
using Demo.Mmose.Core.Common.SafeCollections;
using Demo.Mmose.Core.Entity.Item;
using Demo.Mmose.Core.Util;
#endregion

namespace Demo.Mmose.Core.Entity.Creature.Suit
{
    /// <summary>
    /// 
    /// </summary>
    public class BagManager<ContainerT, ItemT>
        where ContainerT : ItemContainer<ItemT>
        where ItemT : BaseItem
    {
        #region zh-CHS 共有属性 | en Public Properties

        #region zh-CHS Owner 属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private BaseCreature m_Owner = null;
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public BaseCreature Owner
        {
            get { return m_Owner; }
            set { m_Owner = value; }
        }

        #endregion

        #region zh-CHS MinSlot属性 | en Public Properties
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private long m_MinSlot = 0;
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public long MinSlot
        {
            get { return m_MinSlot; }
            protected set
            {
                m_MinSlot = value;

                if ( value < 0 )
                    throw new ArgumentOutOfRangeException( "value", "BagManager<T>.MinSlot - value < 0 error!" );

                if ( value > m_MaxSlot )
                    throw new ArgumentException( "value", "BagManager<T>.MinSlot - value > m_MaxSlot error!" );
            }
        }
        #endregion

        #region zh-CHS MaxSlot属性 | en Public Properties
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private long m_MaxSlot = long.MaxValue;
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public long MaxSlot
        {
            get { return m_MaxSlot; }
            protected set
            {
                if ( value < 0 )
                    throw new ArgumentOutOfRangeException( "value", "BagManager<T>.MaxSlot - value < 0 error!" );

                if ( value < m_MinSlot )
                    throw new ArgumentException( "value", "BagManager<T>.MaxSlot - value < m_MinSlot error!" );

                m_MaxSlot = value;
            }
        }
        #endregion

        #region zh-CHS IsContainerFull属性 | en Public Properties
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public bool IsContainerFull
        {
            get
            {
                if ( m_ToteContainers.Count < ( ( this.MaxSlot - this.MinSlot ) + 1 ) )
                    return false;
                else
                    return true;
            }
        }
        #endregion

        #region zh-CHS ItemContainer 属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 人物的道具列表
        /// </summary>
        private SafeDictionary<long, ContainerT> m_ToteContainers = new SafeDictionary<long, ContainerT>();
        #endregion
        /// <summary>
        /// 人物的道具列表(包裹与身上)
        /// </summary>
        /// <returns></returns>
        [MultiThreadedWarning( "zh-CHS", "(道具)当前的数组是列表临时产生的,不能保存数组用于以后操作:警告!" )]
        public ContainerT[] ToArray()
        {
            return m_ToteContainers.ToArrayValues();
        }

        #region zh-CHS 共有方法 | en Public Methods

        /// <summary>
        /// 
        /// </summary>
        /// <param name="item"></param>
        public bool AddContainer( long lBagSlot, ContainerT itemContainer )
        {
            if ( itemContainer == null )
                throw new Exception( "BaseBagHandler.AddContainer(...) - itemContainerT == null error!" );

            if ( lBagSlot == ItemContainer<ItemT>.SlotNotSet )
                return false;

            if ( lBagSlot > this.MaxSlot || lBagSlot < this.MinSlot )
                return false;

            EventHandler<BeforeAddItemContainerCallEventArgs<ContainerT, ItemT>> tempBeforeEventArgs = m_ThreadEventBeforeAddItemContainerCall;
            if ( tempBeforeEventArgs != null )
            {
                BeforeAddItemContainerCallEventArgs<ContainerT, ItemT> eventArgs = new BeforeAddItemContainerCallEventArgs<ContainerT, ItemT>( itemContainer, this );
                tempBeforeEventArgs( this, eventArgs );

                if ( eventArgs.IsCancel == true )
                    return false;
            }

            if ( m_ToteContainers.TryAdd( lBagSlot, itemContainer ) == false )
                return false;

            itemContainer.BagSlotId = lBagSlot;

            EventHandler<AfterAddItemContainerCallEventArgs<ContainerT, ItemT>> tempAfterEventArgs = m_ThreadEventAfterAddItemContainerCall;
            if ( tempAfterEventArgs != null )
            {
                AfterAddItemContainerCallEventArgs<ContainerT, ItemT> eventArgs = new AfterAddItemContainerCallEventArgs<ContainerT, ItemT>( itemContainer, this );
                tempAfterEventArgs( this, eventArgs );
            }

            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="item"></param>
        public bool RemoveContainer( long lBagSlot )
        {
            if ( lBagSlot > this.MaxSlot || lBagSlot < this.MinSlot )
                return false;

            ContainerT itemContainer = FindContainerAtSlot( lBagSlot );
            if ( itemContainer == null )
                return false;

            EventHandler<BeforeRemoveItemContainerCallEventArgs<ContainerT, ItemT>> tempBeforeEventArgs = m_ThreadEventBeforeRemoveItemContainerCall;
            if ( tempBeforeEventArgs != null )
            {
                BeforeRemoveItemContainerCallEventArgs<ContainerT, ItemT> eventArgs = new BeforeRemoveItemContainerCallEventArgs<ContainerT, ItemT>( itemContainer, this );
                tempBeforeEventArgs( this, eventArgs );

                if ( eventArgs.IsCancel == true )
                    return false;
            }

            if ( m_ToteContainers.Remove( lBagSlot ) == false )
                return false;

            itemContainer.BagSlotId = ItemContainer<ItemT>.SlotNotSet;

            EventHandler<AfterRemoveItemContainerCallEventArgs<ContainerT, ItemT>> tempAfterEventArgs = m_ThreadEventAfterRemoveItemContainerCall;
            if ( tempAfterEventArgs != null )
            {
                AfterRemoveItemContainerCallEventArgs<ContainerT, ItemT> eventArgs = new AfterRemoveItemContainerCallEventArgs<ContainerT, ItemT>( itemContainer, this );
                tempAfterEventArgs( this, eventArgs );
            }

            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="srcBagSlot"></param>
        /// <param name="dstBagSlot"></param>
        /// <returns></returns>
        public bool SwapSubContainer( long srcBagSlot, long dstBagSlot )
        {
            if ( srcBagSlot > this.MaxSlot || srcBagSlot < this.MinSlot )
                return false;

            if ( dstBagSlot > this.MaxSlot || dstBagSlot < this.MinSlot )
                return false;

            //BaseItemContainerState<T> itemContainerState = m_ItemContainerState;
            //if ( itemContainerState != null )
            //{
            //    if ( itemContainerState.OnRemovingSubItem( itemT, this ) == true )
            //        return false;
            //}

            if ( m_ToteContainers.Swap( srcBagSlot, dstBagSlot, true, false ) == false )
                return false;

            //long tempSlotId = BaseItem.SlotNotSet;
            //itemContainerState.IsUpdateRemoveSubItemCall = true;

            //if ( itemContainerState != null )
            //    itemContainerState.OnRemovedSubItem( itemT, this );

            return true;
        }

        /// <summary>
        /// 找道具
        /// </summary>
        /// <param name="layer"></param>
        /// <returns></returns>
        public ContainerT FindContainerAtSlot( long lContainerSlot )
        {
            return m_ToteContainers.GetValue( lContainerSlot );
        }

        /// <summary>
        /// 
        /// </summary>
        public void Empty()
        {
            m_ToteContainers.Clear();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="item"></param>
        public bool AddToFreeContainerSlot( ContainerT itemContainerT )
        {
            long lItemContainerSlotResult = ItemContainer<ItemT>.SlotNotSet;

            if ( this.FindFreeContainerSlot( ref lItemContainerSlotResult ) == false )
                return false;

            if ( lItemContainerSlotResult == ItemContainer<ItemT>.SlotNotSet )
                return false;

            if ( this.AddContainer( lItemContainerSlotResult, itemContainerT ) == false )
                return false;

            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="layer"></param>
        /// <returns></returns>
        public bool FindFreeContainerSlot( ref long lItemContainerSlotResult )
        {
            if ( this.IsContainerFull == true )
                return false;

            for ( long iIndexSlot = this.MinSlot; iIndexSlot <= this.MaxSlot; iIndexSlot++ )
            {
                ContainerT itemContainerT = FindContainerAtSlot( iIndexSlot );

                if ( itemContainerT == null )
                {
                    lItemContainerSlotResult = iIndexSlot;
                    return true;
                }
            }

            return false;
        }
        #endregion

        #endregion

        #region zh-CHS Count属性 | en Public Properties

        /// <summary>
        /// 
        /// </summary>
        public int Count
        {
            get { return m_ToteContainers.Count; }
        }

        #endregion

        #region zh-CHS ItemCount属性 | en Public Properties

        /// <summary>
        /// 
        /// </summary>
        public int ItemCount
        {
            get
            {
                int iCount = 0;
                foreach ( var container in m_ToteContainers )
                {
                    if ( container.Value == null )
                        continue;

                    iCount += container.Value.Count;
                }

                return iCount;
            }
        }

        #endregion

        #endregion

        #region zh-CHS 共有方法 | en Public Methods

        /// <summary>
        /// 
        /// </summary>
        public void InitBagSlot( long lMinSlot, long lMaxSlot )
        {
            if ( lMinSlot < 0 )
                throw new ArgumentOutOfRangeException( "lMinSlot", "BagManager<T>.InitBagSlot(...) - m_MinSlot < 0 error!" );

            if ( lMaxSlot < 0 )
                throw new ArgumentOutOfRangeException( "lMaxSlot", "BagManager<T>.InitBagSlot(...) - lMaxSlot < 0 error!" );

            if ( lMinSlot > lMaxSlot )
                throw new ArgumentException( "lMinSlot & lMaxSlot", "BagManager<T>.InitBagSlot(...) - lMinSlot > lMaxSlot error!" );

            m_MinSlot = lMinSlot;
            m_MaxSlot = lMaxSlot;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="wowItem"></param>
        /// <returns></returns>
        public ContainerT FindSpecialBag( ItemT item )
        {
            if ( item == null )
                return null;

            ContainerT[] itemContainerArray = this.ToArray();
            if ( itemContainerArray == null )
                return null;

            for ( int iIndex = 0; iIndex < itemContainerArray.Length; iIndex++ )
            {
                ContainerT itemContainer = itemContainerArray[iIndex];
                ItemT[] itemArray = itemContainer.ToArray();
                if ( itemContainerArray == null )
                    continue;

                for ( int iIndex2 = 0; iIndex2 < itemArray.Length; iIndex2++ )
                {
                    if ( itemArray[iIndex2].Serial == item.Serial )
                        return itemContainer;
                }
            }

            return null;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="layer"></param>
        /// <returns></returns>
        public ItemT FindSubItemAtContainerSlot( long lContainerSlot, long lItemSlot )
        {
            ContainerT itemContainer = FindContainerAtSlot( lContainerSlot );
            if ( itemContainer == null )
                return null;

            return itemContainer.FindSubItemAtSlot( lItemSlot );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="baseItem"></param>
        /// <returns></returns>
        public bool AddSubItemToFreeContainer( ItemT item )
        {
            ContainerT[] itemContainerArray = this.ToArray();
            if ( itemContainerArray == null )
                return false;

            for ( int iIndex = 0; iIndex < itemContainerArray.Length; iIndex++ )
            {
                ContainerT itemContainer = itemContainerArray[iIndex];

                if ( itemContainer.AddToFreeSlot( item ) == true )
                    return true;
            }

            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="iContainerSlotForm"></param>
        /// <param name="iItemSlotForm"></param>
        /// <param name="iContainerSlotTo"></param>
        /// <returns></returns>
        public bool MoveSubItemToSpecialContainer( long lContainerSlotForm, long lItemSlotForm, long lContainerSlotTo )
        {
            // 获取容器
            ContainerT itemContainerForm = FindContainerAtSlot( lContainerSlotForm );
            if ( itemContainerForm == null )
                return false;

            // 获取容器里面的道具
            ItemT itemForm = itemContainerForm.FindSubItemAtSlot( lItemSlotForm );
            if ( itemForm == null )
                return false;

            // 获取需要放道具的指定容器
            ContainerT itemContainerTo = FindContainerAtSlot( lContainerSlotTo );
            if ( itemContainerTo == null )
                return false;

            long lRetrunItemSlot = BaseItem.SlotNotSet;

            // 尝试寻找指定容器的空闲位置
            if ( itemContainerTo.TryFindFreeSlot( ref lRetrunItemSlot ) == false )
                return false;

            // 开始移除原来容器里面的道具
            if ( itemContainerForm.RemoveSubItem( lItemSlotForm ) == false )
                return false;

            // 开始添加道具到指定的容器
            if ( itemContainerTo.AddSubItem( lRetrunItemSlot, itemForm ) == false ) // 尝试把道具添加到指定的位置
            {
                if ( itemContainerForm.AddToFreeSlot( itemForm ) == false ) // 尝试把道具添加到空闲的位置
                {
                    if ( itemContainerForm.AddSubItem( lItemSlotForm, itemForm ) == false ) // 如果以上都失败了，就把道具放到原来的位置
                    {
                        if ( itemContainerForm.AddToFreeSlot( itemForm ) == false ) // 还是失败了，则把道具添加到原来容器的空闲位置
                        {
                            if ( this.AddSubItemToFreeContainer( itemForm ) == false ) // 还是失败了，则把道具添加到背包里面的容器的空闲位置
                            {
                                // 致命错误，道具丢失了。
                                throw new Exception( "BagManager.MoveSubItemToSpecialContainer(...) - itemContainerForm.AddToFreeSlot(...) error! (No Complete, Lost itemForm)" );
                            }
                        }
                    }
                }

                return false;
            }
            else
                return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="iContainerSlotForm"></param>
        /// <param name="iItemSlotForm"></param>
        /// <param name="iContainerSlotTo"></param>
        /// <param name="iItemSlotTo"></param>
        /// <returns></returns>
        public bool SwapSubItem( long lContainerSlotForm, long lItemSlotForm, long lContainerSlotTo, long lItemSlotTo )
        {
            // 获取容器
            ContainerT itemContainerForm = FindContainerAtSlot( lContainerSlotForm );
            if ( itemContainerForm == null )
                return false;

            // 获取容器里面的道具
            ItemT itemForm = itemContainerForm.FindSubItemAtSlot( lItemSlotForm );
            if ( itemForm == null )
                return false;

            // 获取需要交换的指定容器
            ContainerT itemContainerTo = FindContainerAtSlot( lContainerSlotTo );
            if ( itemContainerTo == null )
                return false;

            // 获取需要交换的指定容器里面的道具
            ItemT itemTo = itemContainerTo.FindSubItemAtSlot( lItemSlotTo );
            if ( itemTo == null )
                return false;

            // 开始移除原来容器里面的道具
            if ( itemContainerForm.RemoveSubItem( lItemSlotForm ) == false )
                return false;

            // 开始移除交换的指定容器里面的道具
            if ( itemContainerTo.RemoveSubItem( lItemSlotTo ) == false ) // 尝试把道具移除
            {
                if ( itemContainerForm.AddSubItem( lItemSlotForm, itemForm ) == false ) // 如果失败，还原删除的道具
                {
                    if ( itemContainerForm.AddToFreeSlot( itemForm ) == false ) // 如果还原失败，添加原来的道具到原来容器里面的空闲位置
                    {
                        if ( this.AddSubItemToFreeContainer( itemForm ) == false ) // 如果还是失败了，添加到背包里容器的空闲位置
                        {
                            // 致命错误，道具丢失了。
                            throw new Exception( "BagManager.SwapSubItem(...) - itemContainerTo.RemoveSubItem(.1.) error! (No Complete, Lost itemForm)" );
                        }
                    }
                }
            }

            // 开始交换道具
            if ( itemContainerForm.AddSubItem( lItemSlotForm, itemTo ) == false )
            {
                if ( itemContainerForm.AddToFreeSlot( itemTo ) == false ) // 失败了，添加到指定容器的空闲位置
                {
                    if ( this.AddSubItemToFreeContainer( itemTo ) == false ) // 如果还是失败了，添加到背包里容器的空闲位置
                        // 致命错误，道具丢失了。
                        throw new Exception( "BagManager.SwapSubItem(...) - itemContainerForm.AddSubItem(.1.) error! (No Complete, Lost itemForm)" );
                }

                if ( itemContainerTo.AddSubItem( lItemSlotTo, itemForm ) == false )
                {
                    if ( itemContainerTo.AddToFreeSlot( itemForm ) == false ) // 失败了，添加到原来容器的空闲位置
                    {
                        if ( this.AddSubItemToFreeContainer( itemForm ) == false ) // 如果还是失败了，添加到背包里容器的空闲位置
                        {
                            // 致命错误，道具丢失了。
                            throw new Exception( "BagManager.SwapSubItem(...) - itemContainerForm.AddSubItem(.2.) error! (No Complete, Lost itemTo)" );
                        }
                    }
                }
            }

            // 开始交换道具
            if ( itemContainerTo.AddSubItem( lItemSlotTo, itemForm ) == false )
            {
                if ( itemContainerTo.AddToFreeSlot( itemForm ) == false ) // 失败了，添加到指定容器的空闲位置
                {
                    if ( this.AddSubItemToFreeContainer( itemForm ) == false ) // 失败了，添加到背包里面容器的空闲位置
                    {
                        // 致命错误，道具丢失了。
                        throw new Exception( "BagManager.SwapSubItem(...) - itemContainerTo.AddSubItem(...) error!" );
                    }
                }
            }

            return true;
        }

        #endregion

        #region zh-CHS 共有事件 | en Public Event

        #region zh-CHS AddItemContainerCall事件 | en Public Event
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private EventHandler<BeforeAddItemContainerCallEventArgs<ContainerT, ItemT>> m_ThreadEventBeforeAddItemContainerCall;
        /// <summary>
        /// 
        /// </summary>
        private SpinLock m_LockThreadEventBeforeAddItemContainerCall = new SpinLock();
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<BeforeAddItemContainerCallEventArgs<ContainerT, ItemT>> ThreadBeforeAddItemContainerCall
        {
            add
            {
                SpinLockEx.ReliableEnter( ref m_LockThreadEventBeforeAddItemContainerCall );
                try
                {
                    m_ThreadEventBeforeAddItemContainerCall += value;
                }
                finally
                {
                    m_LockThreadEventBeforeAddItemContainerCall.Exit();
                }
            }
            remove
            {
                SpinLockEx.ReliableEnter( ref m_LockThreadEventBeforeAddItemContainerCall );
                try
                {
                    m_ThreadEventBeforeAddItemContainerCall -= value;
                }
                finally
                {
                    m_LockThreadEventBeforeAddItemContainerCall.Exit();
                }
            }
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private EventHandler<AfterAddItemContainerCallEventArgs<ContainerT, ItemT>> m_ThreadEventAfterAddItemContainerCall;
        /// <summary>
        /// 
        /// </summary>
        private SpinLock m_LockThreadEventAfterAddItemContainerCall = new SpinLock();
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<AfterAddItemContainerCallEventArgs<ContainerT, ItemT>> ThreadAfterAddItemContainerCall
        {
            add
            {
                SpinLockEx.ReliableEnter( ref m_LockThreadEventAfterAddItemContainerCall );
                try
                {
                    m_ThreadEventAfterAddItemContainerCall += value;
                }
                finally
                {
                    m_LockThreadEventAfterAddItemContainerCall.Exit();
                }
            }
            remove
            {
                SpinLockEx.ReliableEnter( ref m_LockThreadEventAfterAddItemContainerCall );
                try
                {
                    m_ThreadEventAfterAddItemContainerCall -= value;
                }
                finally
                {
                    m_LockThreadEventAfterAddItemContainerCall.Exit();
                }
            }
        }
        #endregion

        #region zh-CHS RemoveItemContainerCall事件 | en Public Event
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private EventHandler<BeforeRemoveItemContainerCallEventArgs<ContainerT, ItemT>> m_ThreadEventBeforeRemoveItemContainerCall;
        /// <summary>
        /// 
        /// </summary>
        private SpinLock m_LockThreadEventBeforeRemoveItemContainerCall = new SpinLock();
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<BeforeRemoveItemContainerCallEventArgs<ContainerT, ItemT>> ThreadBeforeRemoveItemContainerCall
        {
            add
            {
                SpinLockEx.ReliableEnter( ref m_LockThreadEventBeforeRemoveItemContainerCall );
                try
                {
                    m_ThreadEventBeforeRemoveItemContainerCall += value;
                }
                finally
                {
                    m_LockThreadEventBeforeRemoveItemContainerCall.Exit();
                }
            }
            remove
            {
                SpinLockEx.ReliableEnter( ref m_LockThreadEventBeforeRemoveItemContainerCall );
                try
                {
                    m_ThreadEventBeforeRemoveItemContainerCall -= value;
                }
                finally
                {
                    m_LockThreadEventBeforeRemoveItemContainerCall.Exit();
                }
            }
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private EventHandler<AfterRemoveItemContainerCallEventArgs<ContainerT, ItemT>> m_ThreadEventAfterRemoveItemContainerCall;
        /// <summary>
        /// 
        /// </summary>
        private SpinLock m_LockThreadEventAfterRemoveItemContainerCall = new SpinLock();
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<AfterRemoveItemContainerCallEventArgs<ContainerT, ItemT>> ThreadAfterRemoveItemContainerCall
        {
            add
            {
                SpinLockEx.ReliableEnter( ref m_LockThreadEventAfterRemoveItemContainerCall );
                try
                {
                    m_ThreadEventAfterRemoveItemContainerCall += value;
                }
                finally
                {
                    m_LockThreadEventAfterRemoveItemContainerCall.Exit();
                }
            }
            remove
            {
                SpinLockEx.ReliableEnter( ref m_LockThreadEventAfterRemoveItemContainerCall );
                try
                {
                    m_ThreadEventAfterRemoveItemContainerCall -= value;
                }
                finally
                {
                    m_LockThreadEventAfterRemoveItemContainerCall.Exit();
                }
            }
        }
        #endregion

        #region zh-CHS ThreadLostItemCall事件 | en Public Event
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private EventHandler<LostItemCallEventArgs<ContainerT, ItemT>> m_ThreadEventLostItemCall;
        /// <summary>
        /// 
        /// </summary>
        private SpinLock m_LockThreadEventLostItemCall = new SpinLock();
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<LostItemCallEventArgs<ContainerT, ItemT>> ThreadLostItemCall
        {
            add
            {
                SpinLockEx.ReliableEnter( ref m_LockThreadEventLostItemCall );
                try
                {
                    m_ThreadEventLostItemCall += value;
                }
                finally
                {
                    m_LockThreadEventLostItemCall.Exit();
                }
            }
            remove
            {
                SpinLockEx.ReliableEnter( ref m_LockThreadEventLostItemCall );
                try
                {
                    m_ThreadEventLostItemCall -= value;
                }
                finally
                {
                    m_LockThreadEventLostItemCall.Exit();
                }
            }
        }
        #endregion

        #endregion
    }
}
#endregion